package game;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random ;
import java.awt.event.MouseListener ;
import java.awt.event.MouseEvent ;
import java.awt.event.InputEvent ;
import java.awt.image.MemoryImageSource;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.LinkedList;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.Timer;

public class Rev_Trust extends Game {
/*Player playing is player 2 and player 1 is virtual player*/
    double increment;
    double multiplier;

    double money_expected = 0.0 ;   /* Money expected by p2 */
    double p1_money_passed = 0.0 ;  /* Money passed by virtual player*/
    double p1_init_money =3.0 ;     /* Initial money given to p1*/
    double money_passed =0.0 ;      /* Money passed to player 1 by player 2*/
    double p2_money_ava = 0.0 ;     /* Money available for P2 to keep or pass */
    double p1_money_expects = 0.0 ; /* P2 thinks P1 expects this much money from him*/
    double money_won = 0.0 ;        /* money won by p2*/
    boolean count = false ;
    String stage = "1" ;            /* Maintains the state in which the game is.*/
    int totalTime=60,secs = totalTime, timeTaken=0, thinkTimeTaken=0, thinkSecs=0;
    Timer time = new Timer(1000, new TimeListener());
    Timer thinkTime = new Timer(1000, new ThinkTimeListener());

	/** List of values that user can choose to send. Used in chooser JList. */
	LinkedList<String> moneyValues = new LinkedList<String>();

	/** Number of values to display in the chooser JList. */
	final int LIST_SIZE = 5;

	/** Half of list size. */
	int halfList;

	/** Maximum number of values the user could possibly choose given the
	 increment, and starting and stopping values. */
	int maxValues;

	/** List index we've displayed for the chooser list. */
	int listIndex = 0;

	/** Amount of time, in seconds, the subject spent making their decision. */
	int playerThinkTime = 0;

	// Game log constants.
	final int GL_GIVE = 1; // How much money p2 thinks p1 will give.
	final int GL_RETURN = 2; // How much money p2 returns to p1.
	final int GL_GUESS = 3; // How much money p2 thinks p1 expects p2 to return.
	final int GL_RECEIVE = 4; // How much money p2 gets from p1.

    /** Creates new form Rev_Trust */
    public Rev_Trust() {
        super();
//        super("",
//              false, //resizable
//              false, //closable
//              false, //maximizable
//              false);//iconifiable
//        javax.swing.plaf.InternalFrameUI ui = this.getUI();
//        ((javax.swing.plaf.basic.BasicInternalFrameUI)ui).setNorthPane(null);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

        p1_init_money =3.0 ;
        increment = 0.25;
        multiplier = 2;
        initComponents();
        l2.setText ("First player has "
			+ String.format ("$%.2f", p1_init_money));
        this.setVisible(true);
        setLocation(screenSize.width/2-400, screenSize.height/2-300);

        addMouseListener( new Rev_Trust.CheckMouse());
        lblBottom.setVisible(false);
		initMoneyList();

        time.start();
        updateTimerLabel();

        hideMouse();
    }

    public Rev_Trust (String params, int currentRep) {
            super();
//            super("",
//              false, //resizable
//              false, //closable
//              false, //maximizable
//              false);//iconifiable
//        javax.swing.plaf.InternalFrameUI ui = this.getUI();
//        ((javax.swing.plaf.basic.BasicInternalFrameUI)ui).setNorthPane(null);
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

		String paramPart[] = params.split (",");
		p1_init_money = Double.parseDouble(paramPart[2]);
        increment = Double.parseDouble(paramPart[3]);
        multiplier = Double.parseDouble(paramPart[4]);
		this.params = params;
		repTot = Integer.parseInt (paramPart[1]);
		repNum = currentRep;
        
        initComponents();
        l2.setText ("First player has "
			+ String.format ("$%.2f", p1_init_money));
        this.setVisible(true);
        setLocation(screenSize.width/2-400, screenSize.height/2-300);
		initMoneyList();
		secs = totalTime;
		updateTimerLabel();

        runner.addMouseListener( new Rev_Trust.CheckMouse());
        addMouseListener( new Rev_Trust.CheckMouse());
		moneyList.addMouseListener (new Rev_Trust.CheckMouse());
		this.getGlassPane().addMouseListener(new Rev_Trust.CheckMouse());

        lblBottom.setVisible(false);

        time.start();
        updateTimerLabel();

        hideMouse();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lblLeft = new javax.swing.JLabel();
        lblRight = new javax.swing.JLabel();
        l1 = new javax.swing.JLabel();
        l2 = new javax.swing.JLabel();
        l5 = new javax.swing.JLabel();
        lblTime = new javax.swing.JLabel();
        lblBottom = new javax.swing.JLabel();
        moneyScroll = new javax.swing.JScrollPane();
        moneyList = new javax.swing.JList();

        setBackground(new java.awt.Color(255, 255, 255));
        setBorder(null);
        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setMaximumSize(new java.awt.Dimension(800, 600));
        setMinimumSize(new java.awt.Dimension(800, 600));
        setPreferredSize(new java.awt.Dimension(800, 600));

        lblLeft.setBackground(new java.awt.Color(255, 255, 255));
        lblLeft.setFont(new java.awt.Font("Tahoma", 0, 18));
        lblLeft.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblLeft.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/redSelect.png"))); // NOI18N
        lblLeft.setOpaque(true);

        lblRight.setBackground(new java.awt.Color(255, 255, 255));
        lblRight.setFont(new java.awt.Font("Tahoma", 0, 18));
        lblRight.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblRight.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/greenDone.png"))); // NOI18N
        lblRight.setOpaque(true);

        l1.setFont(new java.awt.Font("Calibri", 1, 28));
        l1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        l1.setText("You are Player 2");

        l2.setBackground(new java.awt.Color(255, 255, 255));
        l2.setFont(new java.awt.Font("Calibri", 1, 30)); // NOI18N
        l2.setForeground(new java.awt.Color(0, 51, 255));
        l2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        l2.setText("Player 1 has");

        l5.setFont(new java.awt.Font("Calibri", 1, 30));
        l5.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        l5.setText("How much do you expect the player 1 to pass ?");

        lblTime.setFont(new java.awt.Font("Calibri", 1, 36));
        lblTime.setForeground(new java.awt.Color(153, 102, 0));
        lblTime.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/hrGlass.png"))); // NOI18N
        lblTime.setText("3:00");

        lblBottom.setBackground(new java.awt.Color(255, 255, 255));
        lblBottom.setFont(new java.awt.Font("Tahoma", 0, 18));
        lblBottom.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblBottom.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/redSend.png"))); // NOI18N
        lblBottom.setOpaque(true);

        moneyList.setFont(new java.awt.Font("Tahoma", 1, 24));
        moneyList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "$0.00", "$0.25", "$0.50", "$0.75", "$1.00" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        moneyList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        moneyList.setVisibleRowCount(5);
        moneyList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                moneyListValueChanged(evt);
            }
        });
        moneyScroll.setViewportView(moneyList);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .add(lblTime, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 780, Short.MAX_VALUE)
                .addContainerGap())
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .add(l1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 780, Short.MAX_VALUE)
                .addContainerGap())
            .add(layout.createSequentialGroup()
                .add(104, 104, 104)
                .add(lblLeft, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(125, 125, 125)
                .add(lblRight, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(105, 105, 105))
            .add(layout.createSequentialGroup()
                .add(279, 279, 279)
                .add(lblBottom, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(288, 288, 288))
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(l2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 780, Short.MAX_VALUE)
                .addContainerGap())
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(l5, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 780, Short.MAX_VALUE)
                .addContainerGap())
            .add(layout.createSequentialGroup()
                .add(334, 334, 334)
                .add(moneyScroll, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 128, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(338, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(lblTime, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 48, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(35, 35, 35)
                .add(l1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 39, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(18, 18, 18)
                .add(l2)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(l5)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(moneyScroll, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 160, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .add(18, 18, 18)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(lblRight)
                    .add(lblLeft))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 30, Short.MAX_VALUE)
                .add(lblBottom))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

	private void moneyListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_moneyListValueChanged
		moneyList.setSelectedIndex(halfList);
}//GEN-LAST:event_moneyListValueChanged

	/**
     * Based on the time remaining, updates the time remaining label.
     */
    private void updateTimerLabel() {
        int min = secs / 60;
        int sec = secs % 60;
        lblTime.setText (min + ":" + ((sec < 10) ? "0" : "") + sec);
    }

	@Override
	public synchronized void addMouseListener(MouseListener l) {
		super.addMouseListener(l);
	}

    class CheckMouse implements MouseListener{
         public void mousePressed(MouseEvent e) { hideMouse(); }
         public void mouseReleased(MouseEvent e) {}
         public void mouseEntered(MouseEvent e) {}
         public void mouseExited(MouseEvent e) {}
         public void mouseClicked(MouseEvent e) {
            int modifiers = e.getModifiers();
            if ((modifiers & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
				if( stage.equals("1") ) {
					incrementMoneyList();
					String money =
						moneyList.getSelectedValue().toString().substring (1);
					money_expected = Double.parseDouble (money);
				}
				else if( stage.equals("2") ) {
					incrementMoneyList();
					String money =
						moneyList.getSelectedValue().toString().substring (1);
					money_passed = Double.parseDouble (money);
				}
				else if( stage.equals("3") ){
					incrementMoneyList();
					String money =
						moneyList.getSelectedValue().toString().substring (1);
					p1_money_expects = Double.parseDouble (money);
				}
				else if( stage.equals("4")){
					stage = "5" ;
					lblBottom.setVisible(false);
					l2.setText("") ;
					money_won = p2_money_ava - money_passed;
					timeTaken = totalTime - secs ;

					double p1Wins = p1_init_money - p2_money_ava/multiplier
						+ money_passed;
					writeLog (playerId + ",2,\"" + params + "\"," + repNum
						+ "," + repTot + ","
						+ String.format ("$%.2f", money_won)
						+ "," + String.format ("$%.2f", p1Wins));
					writeGameLog (playerId + ",2," + playerThinkTime + ","
						+ GL_RECEIVE + ","
						+ String.format ("$%.2f", p2_money_ava/multiplier));
					playerThinkTime = 0;

					totalMoneyWon += money_won ;
					System.out.println("G.totalMoneyWon = " + totalMoneyWon) ;

					secs=0;
				}
				else if( stage.equals("5") ){}
				else if(stage.equals("Think")) {}
            }
            if ((modifiers & InputEvent.BUTTON2_MASK) == InputEvent.BUTTON2_MASK) {}
            if ((modifiers & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK) {
                if( stage.equals("1") ) {
                    writeGameLog (playerId + ",2," + playerThinkTime + ","
						+ GL_GIVE + ","
						+ String.format ("$%.2f", money_expected));
					playerThinkTime = 0;

					stage = "2";
                    calculateResult();
                    S1() ;
                }
                else if( stage.equals("2") ) {
					writeGameLog (playerId + ",2," + playerThinkTime + ","
						+ GL_RETURN + ","
						+ String.format ("$%.2f", money_passed));
					playerThinkTime = 0;

                    stage = "3" ;
                    S3() ;
                }
                else if( stage.equals("3") ) {
					writeGameLog (playerId + ",2," + playerThinkTime + ","
						+ GL_GUESS + ","
						+ String.format ("$%.2f", p1_money_expects));
					playerThinkTime = 0;

                    stage = "4" ;
                    S4() ;
                }
                else if( stage.equals("5") ){
                }
                else if(stage.equals("Think")) {

                }
            }
        }
    }

    private void hideMouse() {
        int[] pixels = new int[16 * 16];
        Image image = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(16, 16, pixels, 0, 16));
        Cursor transparentCursor = Toolkit.getDefaultToolkit().createCustomCursor(image, new Point(0, 0), "invisibleCursor");
        this.getGlassPane().setCursor(transparentCursor);
		this.getGlassPane().setVisible(true);
        runner.setCursor(transparentCursor);
    }

	/**
     * Reset the money list to its initial state.
     */
	private void initMoneyList() {
		// Assuming no loss of precision.
		moneyValues.clear();
		if (stage.equals("1"))
			maxValues = (int) (p1_init_money / increment) + 1;
		else
			maxValues = (int) (p2_money_ava / increment) + 1;
		halfList = (int) Math.floor (LIST_SIZE / 2);
		int numValues = maxValues - halfList + LIST_SIZE;
		for (listIndex = maxValues-halfList;
			listIndex < numValues; listIndex++) {
			moneyValues.add (String.format ("$%.2f",
				increment * (listIndex % maxValues)));
		}
		listIndex--;
		moneyList.setListData(moneyValues.toArray(new String [LIST_SIZE]));
		moneyList.setSelectedIndex(halfList);
		moneyList.setVisible (true);
		moneyScroll.setVisible (true);
	}

	/**
     * Shift the money list to increase by one place.
     */
    private void incrementMoneyList() {
		listIndex++;
		moneyValues.remove();
		moneyValues.add (String.format ("$%.2f",
			increment * (listIndex % maxValues)));
		moneyList.setListData (
			moneyValues.toArray(new String [LIST_SIZE]));
		moneyList.setSelectedIndex (halfList);
    }

   public void calculateResult() {
        String line ;
        Random r = new Random();
        double probability = 0, cumm_prob =0 ;
        probability = r.nextDouble();
        System.out.println("probability: " + probability);
        try {
            BufferedReader bin = readGameData() ;
            line = bin.readLine() ;
            line = bin.readLine() ; 
            while( line != null ) {
                String str[] = line.split(",") ;
                cumm_prob += Double.parseDouble(str[0]) ;
                System.out.println("Cummalative : " + cumm_prob);
                if( probability > cumm_prob ){
                    line = bin.readLine() ;
                    continue ;
                }
                else{
                    System.out.println("Match: " + str[0] + " " + str[1]);
                    p1_money_passed = Double.parseDouble(str[1]) ;
                    p2_money_ava = multiplier * p1_money_passed ;
                    System.out.println("p2_money_ava " + p2_money_ava);
                    break ;
                }
            }
        }
        catch( IOException e ){
             e.printStackTrace();
             logError(e);
        }

   }

    class TimeListener implements ActionListener {
    	 public void actionPerformed(ActionEvent e) {
    		secs--;
			playerThinkTime++;
            if(secs>=0) {
                updateTimerLabel();
            }
            if(secs==0) {
                //time.stop();
                moneyList.setVisible (false);
				moneyScroll.setVisible (false);
                lblLeft.setVisible(false);
                lblRight.setVisible(false);
                stage="5";
                l2.setText(null);
                l5.setText("Sorry, your time is up.");

				writeLog (playerId + ",2,\"" + params + "\"," + repNum
					+ "," + repTot + ",TimeOut,TimeOut");
				writeGameLog (playerId + ",2," + playerThinkTime
					+ ",TimeOut,TimeOut");
				
                totalMoneyWon += 0.0 ;
                System.out.println("G.totalMoneyWon = " + totalMoneyWon) ;
            }
            if(secs==-6) {
                time.stop();
                try {
                    setVisible(false);
                    free=true;
                } catch(Exception ex) {
                    ex.printStackTrace();
                    logError(ex);
                }
            }
    	}
    }

    class ThinkTimeListener implements ActionListener {
    	 public void actionPerformed(ActionEvent e) {
    		thinkSecs--;
            if(thinkSecs==0) {
                thinkTime.stop();
                lblLeft.setVisible(true);
                lblRight.setVisible(true);
                time.start();

                stage = "2" ;
                S2() ;
            }
    	}
    }

    public void S1() {
		Random r = new Random();
		thinkSecs = r.nextInt(5) + 3; // 3 - 7 second wait.
		thinkTimeTaken = thinkSecs;
		time.stop();
		l5.setText(null);
		lblLeft.setVisible(false);
		lblRight.setVisible(false);
		l2.setText("Waiting for the first player to pass some money...");
		moneyList.setVisible (false);
		moneyScroll.setVisible (false);

		System.out.println("Thinking simulation for "+thinkSecs+" secs");

		thinkTime.start();
		stage="Think";
    }

    public void S2() {
		secs = totalTime;
		updateTimerLabel();
        l5.setText("What would you like to give to the other player?") ;
        initMoneyList();
        l2.setText("First player passed "
			+ String.format ("$%.2f", p1_money_passed));
    }

    public void S3() {
		secs = totalTime;
		updateTimerLabel();
        initMoneyList();
        l5.setText("How much do you think the first player expects you to return?");
        l2.setText("You gave " + String.format("$%.2f", money_passed));
    }

    public void S4(){
        moneyList.setVisible (false);
		moneyScroll.setVisible (false);
        l5.setVisible(false) ;
        lblLeft.setVisible(false);
        lblRight.setVisible(false);
        lblBottom.setVisible(true);
        
    }
    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        try {
            JFrame main = new JFrame();
            JDesktopPane dPane = new JDesktopPane();
            Rev_Trust frame = new Rev_Trust();
            main.setSize(820, 620);
            dPane.add(frame);
            main.add(dPane);
            main.setVisible(true);
            dPane.setVisible(true);
            frame.setSelected(true);
            frame.setVisible(true);
            } catch(Exception ex) {
            ex.printStackTrace();
            }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel l1;
    private javax.swing.JLabel l2;
    private javax.swing.JLabel l5;
    private javax.swing.JLabel lblBottom;
    private javax.swing.JLabel lblLeft;
    private javax.swing.JLabel lblRight;
    private javax.swing.JLabel lblTime;
    private javax.swing.JList moneyList;
    private javax.swing.JScrollPane moneyScroll;
    // End of variables declaration//GEN-END:variables
}
